#include "Header.h"


extern "C"{

	bool cleanup(bool ret, HANDLE hProcess){
		CloseHandle(hProcess);
		return ret;
	}


bool __declspec(dllexport) inject(char *dll){
	int procId, check;
	HANDLE hProcess, hThread;
	LPVOID addr, arg;
	//auto cleanup = [&](bool ret)->bool{CloseHandle(hProcess); return ret;};

	while((procId = findProcess()) == 0) Sleep(1000);
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
	if(hProcess == 0)
		return false;
	addr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
	if(addr == 0)
		return cleanup(false, hProcess);
	arg = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	if(arg == 0)
		return cleanup(false, hProcess);
	check = WriteProcessMemory(hProcess, arg, dll, strlen(dll), NULL);
	if(check == 0)
		return cleanup(false, hProcess);
	hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
	if(hThread == 0)
		return cleanup(false, hProcess);
	else
		return cleanup(true, hProcess);
}	


int findProcess(){
	DWORD processes[1024], cbNeeded, cProcesses, cbNeed;
	HANDLE hProcess;
	HMODULE hMod;
	unsigned int i;
	TCHAR procName[MAX_PATH] = TEXT("unknown");

	if(!EnumProcesses(processes, sizeof(processes), &cbNeeded))
		return -1;
	cProcesses = cbNeeded/sizeof(DWORD);
	for(i = 0; i < cProcesses; i++){
		if(processes[i] != 0){
			hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processes[i]);
			if(hProcess != 0 && EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeed)){
				GetModuleBaseName(hProcess, hMod, procName, sizeof(procName)/sizeof(TCHAR));
				if(strcmp(PROC_NAME, procName) == 0){
					CloseHandle(hProcess);
					return processes[i];
				}
			}
			if(hProcess != 0)
				CloseHandle(hProcess);
		}
	}
	return 0;
}

}